#include "SDLCanvas.h"

#include <iostream>

#include "sdl.h"
#include "gl.h"

#include "GLContext.h"

namespace catan
{

const float SDLCanvas::CLIENT_UNIT_WIDTH = 1.0f;
const float SDLCanvas::CLIENT_UNIT_HEIGHT = 0.75f;

SDLCanvas::SDLCanvas(GameState &gameState): width(800), height(600), gameStateRef(&gameState)
{
	if (!gameStateRef->isRunning())
	{
		return;
	}
	
	const SDL_VideoInfo *videoInfo;
	
	//init sdl
	if (SDL_Init(SDL_INIT_VIDEO) < 0 ) {
	    std::cerr << "SDL initialization failed: " << SDL_GetError() << std::endl;
	    gameStateRef->end();
	    return;
	}
	
    videoInfo = SDL_GetVideoInfo();
    if (!videoInfo)
	{
	    std::cerr << "Video query failed: " << SDL_GetError() << std::endl;
	    gameStateRef->end();
	    return;
	}
    
    videoFlags = SDL_OPENGL;
    videoFlags |= SDL_GL_DOUBLEBUFFER;
    videoFlags |= SDL_HWPALETTE;
    videoFlags |= SDL_RESIZABLE;
   	videoFlags |= (videoInfo->hw_available ? SDL_HWSURFACE : SDL_SWSURFACE);
   	videoFlags |= (videoInfo->blit_hw ? SDL_HWACCEL : 0);

   	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, GL_TRUE);
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 16);
    this->resizeWindow(width, height);
}

bool SDLCanvas::resizeWindow(int width, int height)
{
	this->width = width;
	this->height = height;
	if (!SDL_SetVideoMode(width, height, 32, videoFlags))
	{
	    std::cerr << "Could not set the video mode: " << SDL_GetError() << std::endl;
	    gameStateRef->end();
	    return false;
	}
    float wOverH = (float)width / height;
    bool widthIsSmaller = (3*width < 4*height);
    windowUnitWidth = (widthIsSmaller ? CLIENT_UNIT_WIDTH : CLIENT_UNIT_HEIGHT * wOverH);
    windowUnitHeight = (widthIsSmaller ? CLIENT_UNIT_WIDTH / wOverH : CLIENT_UNIT_HEIGHT);
	return true;
}

bool SDLCanvas::updateViewport()
{
	if (!gameStateRef->isRunning())
	{
		return false;
	}
	glViewport(0, 0, width, height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
    gluPerspective(45.0f, (GLfloat)width/height, 0.1f, 100.0f);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	return true;
}

SDLCanvas::~SDLCanvas()
{
}

int SDLCanvas::getWidth() const
{
	return width;
}

int SDLCanvas::getHeight() const
{
	return height;
}

float SDLCanvas::getWindowUnitWidth() const
{
	return windowUnitWidth;
}

float SDLCanvas::getWindowUnitHeight() const
{
	return windowUnitHeight;
}

float SDLCanvas::getClientUnitWidth() const
{
	return CLIENT_UNIT_WIDTH;
}

float SDLCanvas::getClientUnitHeight() const
{
	return CLIENT_UNIT_HEIGHT;
}

}
